﻿using System.Text.Json;
using Microsoft.Extensions.Configuration;
using StackExchange.Redis;
using Volo.Abp.DependencyInjection;

namespace Linker.TaskCenter.Helpers
{
    public class RedisSubscribeHelper : ISingletonDependency
    {
        public delegate void GetSubscribeMessageDelegate(string message);

        private readonly IConfiguration _configuration;

        public RedisSubscribeHelper(IConfiguration configuration)
        {
            _configuration = configuration;
        }

        public void Publish(object data, string chancel)
        {
            var subscriber = GetSubscriber();
            var db = GetDatabase();
            var message = JsonSerializer.Serialize(data);
            db.ListRightPush(chancel, message);
            subscriber.Publish(new RedisChannel(chancel, RedisChannel.PatternMode.Auto), RedisValue.EmptyString);
        }

        public void PublishAsync(object data, string chancel)
        {
            var subscriber = GetSubscriber();
            var db = GetDatabase();
            var message = JsonSerializer.Serialize(data);
            db.ListRightPush(chancel, message);
            subscriber.PublishAsync(new RedisChannel(chancel, RedisChannel.PatternMode.Auto), RedisValue.EmptyString);
        }

        public void Subscribe(string subChancel, GetSubscribeMessageDelegate action)
        {
            var subscriber = GetSubscriber();
            subscriber.Subscribe(new RedisChannel(subChancel, RedisChannel.PatternMode.Auto),
                (chancel, message) => { action?.Invoke(message); });
        }

        public void SubscribeAsync(string subChancel, GetSubscribeMessageDelegate action)
        {
            var subscriber = GetSubscriber();
            subscriber.SubscribeAsync(new RedisChannel(subChancel, RedisChannel.PatternMode.Auto),
                (chancel, message) => { action?.Invoke(message); });
        }

        public ISubscriber GetSubscriber(string connectionString = "")
        {
            var connection =
                ConnectionMultiplexer.Connect(string.IsNullOrEmpty(connectionString)
                    ? "127.0.0.1"
                    : _configuration["Redis:Configuration"]);
            return connection.GetSubscriber();
        }

        public IDatabase GetDatabase(string connectionString = "")
        {
            var connection =
                ConnectionMultiplexer.Connect(string.IsNullOrEmpty(connectionString)
                    ? "127.0.0.1"
                    : _configuration["Redis:Configuration"]);
            return connection.GetDatabase();
        }
    }
}